Gli schermi Prima di utilizzare una qualsiasi risorsa Intuition occorre aprire l'intuition.library dato che utilizzeremo le sue funzioni. Bene iniziamo col descrivere gli schermi; nelle vecchie versioni del chip set di Amiga esistevano solo 4 risoluzioni possibili (320x256, 320x512, 640x256, 640x512) di cui due (quelle di ampiezza di 320 pixels) potevano arrivare a 32 colori su una palette di 4096 e utilizzare particolari modalità come l'EHB (Extra Half Brite) e l'HAM (Hold And Modify) che permettevano rispettivamente, con alcune limitazioni, di raggiungere 64 e 4096 colori, mentre quelle con 640 pixels di ampiezza dovevano accontentarsi di un massimo di 16 colori. L'avvento dell'ECS ha portato solo qualche nuova risoluzione, mentre la vera rivoluzione si è avuta con l'AGA, data la sua possibile riprogrammazione delle frequenze video si possono ottenere una miriade di nuove risoluzioni, tutte con un massimo di 256 colori su una palette di 16.7 milioni di colori circa, e tutte con la possibilità di utilizzare la modalità HAM8, che permette di visualizzare con qualche limitazione tutta la palette di 16.7 milioni (attenzione però non si tratta di true-color, anzi in questa modalità lo schermo viene memorizzato sempre con 8 bitplanes). Come già accennato, possono esistere più schermi contemporaneamente sul vostro video, ed inoltre gli schermi possono essere di due tipi: public e custom; gli schermi custom vengono utilizzati solo dai programmi che li creano, per cui le finestre visualizzate su di essi possono essere create solo dall'applicazione che ha aperto gli schermi; gli schermi public sono "pubblici", vale a dire che possono essere utilizzati anche da altre applicazioni; quindi una finestra creata da un programma, in cui non viene specificato su quale schermo essere visualizzata può andare a finire su uno di questi schermi public; uno schermo public è il workbench e prima della versione 2.0 del sistema era l'unico possibile. La struttura che identifica uno schermo e che ne contiene tutte le informazioni necessarie è la struttura Screen. Le funzioni principali di intuition.library che riguardano gli schermi sono OpenScreenTags(), OpenScreenTagList(), OpenScreen() e CloseScreen(); le prime tre servono per la creazione di uno schermo, mentre l'ultima per la sua chiusura e per liberare la memoria occupata da questo. Le prime due funzioni di apertura sono molto simili e sono state introdotte dalla versione 2.0 (V36) del sistema, perché usano un modo molto efficiente per il passaggio di parametri, denominato per "Tags" introdotto appunto nel 2.0 e che ritroveremo in moltre altre funzioni di libreria; la creazione dei Tags è avvenuta nel 2.0 perché in quel momento ci si è posti il problema del passaggio di parametri; infatti prima i parametri per l'apertura dello schermo, venivano passati mediante una struttura NewScreen contenente le diverse caratteristiche di quest'ultimo; dato il radicale cambiamento del sistema nel 2.0 molti parametri sono stati aggiunti e quindi, si è posto l'accento sulla compatibilità con versioni future del sistema (infatti il NewScreen non valeva più a molto, ed è stato mantenuto per compatibilità con il vecchio sistema), per cui è stato creato il Tag; il Tag è una struttura di due elementi, di cui il primo contiene un valore identificatore che indica quale parametro si vuole passare, ed il secondo rappresenta il parametro vero e proprio; in questa maniera si può passare alla funzione una lista di tags che contengono i diversi parametri e, dato che il numero di tags è variabile, la compatibilità con il futuro è assicurata; in più se qualche parametro (ad esempio una vecchia chiamata con una nuova funzione) non dovesse essere passato, il sistema provvederà ad utilizzare un valore standard per quella caratteristica. Come prima avevamo accennato esistono due funzioni per l'apertura dello schermo mediante tag, OpenScreenTags() e OpenScreenTagList(); la differenza consiste semplicemenete che, nella prima funzione i tags vengono passati come parametri della procedura, mentre nella seconda viene passato il puntatore ad un array di tags; dato che il numero di parametri con questo metodo è variabile, vi starete chiedendo come si fà ad indicare alla procedura che la lista è finita; per indicare che la lista è finita, basta semplicemente inserire come ultimo tag un codice speciale che indica appunto la fine della lista, ed è una costante di un file di inclusione: TAG_END, oppure TAG_DONE Dopo questa piccola parentesi, analizziamo le funzioni di apertura dello schermo: schermo = OpenScreenTags(nuovoschermo,tagId1,tagVal1,TagId2,TagVal2,.....); dove "schermo" è il puntatore alla struttura Screen identificante lo schermo creato, o NULL se l'operazione è fallita; "nuovoschermo" è il puntatore alla struttura NewScreen (utilizzando i tag può essere tranquillamente impostato a NULL) e dopo seguono la lista di tag degli attributi dello schermo che devono ultimare, lo ricordiamo, con TAG_END o TAG_DONE. schermo = OpenScreenTagList(nuovoschermo,listatags); dove "listatags" è il puntatore ad un array di strutture TagItem; TagItem è la struttura contenente i due valori del "tag" ed ha la seguente forma: struct TagItem { ULONG ti_Tag; /* codice dell'attributo */ ULONG ti_Data; /* valore dell'attributo */ }; potete vedere i diversi utilizzi di OpenScreenTags e OpenScreenTagList negli esempi, ma oramai la differenza dovrebbe essere chiara. schermo = OpenScreen(nuovoschermo); OpenScreen è la vecchia funzione di apertura degli schermi, utilizzata normalmente prima della versione 2.0 del sistema ed il passaggio dei parametri avviene mediante la struttura NewScreen; vi è comunque la possibilità di sfruttare le nuove qualità degli schermi del 2.0 utilizzando questa funzione, mediante la struttura ExtNewScreen; questa struttura è praticamente identica a NewScreen fuorché che possiede un campo in più, presente alla fine della struttura, ed è un puntatore all'array di tags degli attributi per lo schermo secondo la modalità vista; la struttura ExtNewScreen deve possedere il bit NS_EXTENDED settato nel campo Type. In questa maniera se il programma gira con una versione del sistema operativo inferiore al 2.0 allora la struttura verrà interpretata come una comunissima NewScreen altrimenti, verrà considerato l'ultimo campo e verrano utilizzato gli attributi del 2.0; da notare che questa possibilita è presente dalla versione V37 del s.o. Come ultima funzione rimane da analizzare CloseScreen: CloseScreen(schermo); CloseScreen come potete immaginare provvede a chiudere uno schermo precedentemente aperto. Torniamo a parlare di schermi pubblici; per poter aprire uno schermo pubblico basta specificare, il tag SA_PubName con il nome pubblico da assegnare allo schermo, nella lista dei tag per la funzione OpenScreenTags; vi sono però molte altre funzioni di intuition che riguardano gli schermi pubblici e che servono per la loro gestione; se volete ad esempio utilizzare uno schermo "public", per aprire una finestra o altro, occorre avere il puntatore alla struttura Screen di quest'ultimo; la funzione che permette di ottenere il puntatore ad uno schermo pubblico con un determinato nome è LockPubScreen; questa funzione ha il compito anche di "bloccare" momentaneamente lo schermo in modo che nessun altro task o sistema ne possa modificare lo stato (chiudendolo ad esempio); in questa maniera si evita di aprire una finestra, proprio mentre il sistema chiude lo schermo (che porterebbe a risultati disastrosi, come potete ben immaginare). Una volta che avete eseguito tutte le operazioni che volevate sullo schermo pubblico occorre sbloccarlo mediante la funzione UnlockPubScreen. Come accennato la volta scorsa esiste uno schermo pubblico di default, che normalmente è il Workbench; lo schermo pubblico di default può però essere cambiato, mediante la funzione SetDeafultPubScreen, oppure si può conoscere quale sia mediante GetDefaultPubScreen. Vi è talvolta la necessità di accedere a tutti i public screens, per avere una lista completa da utilizzare in diversi modi (visualizzandola all'utente per una selezione ad esempio); in questo caso occorre utilizzare la funzione LockPubScreenList che blocca la lista di sistema desgli schermi pubblici; il nodo della lista è descritto mediante la struttura PubScreenNode definita in "intuition/screens.h"; una volta ultimata l'analisi sulla lista degli schermi pubblici bisogna liberarla mediante UnlockPubScreenList. Comunque non serve utilizzare direttamente le informazioni della lista, in quanto basta richiamare la funzione NextPubScreen che restituisce il prossimo schermo da esaminare; quando l'ultimo schermo è stato restituito la funzione ritornerà NULL. DrawInfo e 3D Look Dalla versione 2.0 del sistema si adotta uno speciale gioco di colori, per creare effetti tridimensionali nelle finestre e nei gadget; questi effetti 3D sono ottenuti associando ad un colore una definizione del genere "bordo ombra" o "bordo luminoso", in modo che il sistema sappia a quale colore ricorrere se deve disegnare un bordo illuminato o in ombra; nell'apertura di uno schermo, possono essere specificate in SA_Pens, quali penne corrispondano al colore "illuminato" o "ombra" ed altri; il parametro passato in SA_Pens è un array di WORD che contiene in una determinata posizione, che identifica di quale colore si parla, il codice della penna corrispondente; l'array deve terminare con ~0, per cui se si vuole utilizzare la definizione standard delle penne, basta specificare un array con solo ~0; se invece occorre utilizzare particolari colori, bisogna specificarli nell'array seguendo la tabella delle definizioni (vedere riquadro). L'array delle penne di uno schermo (dri_Pens) è contenuto nella struttura DrawInfo, che contiene tutte le informazioni per il corretto rendering dello schermo e del suo contenuto (dati sui font ecc.). Per ottenere il puntatore alla struttura DrawInfo di uno schermo, bisogna utilizzare la funzione GetScreenDrawInfo con parametro puntatore alla struttura Screen; una volta utilizzata, bisogna liberare tale struttura con FreeScreenDrawInfo. La visuale Nell'apertura dello schermo si può specificare un diverso tipo di overscan tra i seguenti: OSCAN_TEXT OSCAN_STANDARD OSCAN_MAX OSCAN_VIDEO Occorre quindi conoscere qual è la reale risoluzione dello schermo; per questo si può utilizzare la funzione QueryOverscan: ris = QueryOverscan(screen_modeID,rettangolo,tipooverscan); dove "ris" è una LONG che indica successo se ha un valore diverso da zero; "screen_modeID" è la ULONG che identifica il tipo di schermo; "rettangolo" è il puntatore ad una struttura Rectangle contenente i limiti dello schermo; attenzione, la struttura Rectangle non verrà creata dalla funzione, ma dovrete crearla voi e passare alla funzione il suo indirizzo (mediante l'operatore &) in modo che la funzione possa modificarne i campi; il parametro "tipooverscan" specifica il tipo di overscan, scelto fra uno tra quelli descritti prima.